package com.cyt.sys.service.impl;

import com.cyt.base.model.dto.ReturnResult;
import com.cyt.base.util.BaseConstant;
import com.cyt.base.util.BaseUtil;
import com.cyt.base.util.ErrorCode;
import com.cyt.sys.dao.*;
import com.cyt.sys.model.po.*;
import com.cyt.sys.model.vo.SysAppModuleVo;
import com.cyt.sys.service.SysAppModuleService;
import com.cyt.sys.util.DESHelper;
import com.cyt.sys.util.JavaBeanUtil;
import com.cyt.sys.util.PostClient;
import com.cyt.sys.util.RSAHelper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.StringUtil;
import net.sf.json.JSONArray;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;


/**
 *@Author: dingxu
 *@Date: 2019-04-03 8:19
 *@Description:数据字典类型service实现类
 */
@Service("baseAppModuleServiceImpl")
public class SysAppModuleServiceImpl extends BaseServiceImpl<SysAppModule> implements SysAppModuleService {

    @Resource
    private SysAppModuleDao sysAppModuleDao;
    @Resource
    private SysAppMenuDao sysAppMenuDao;
    @Resource
    private SysMenuEnDao sysMenuEnDao;
    @Resource
    private SysMenuDao sysMenuDao;
    @Resource
    private SysParamConfigContentDao sysParamConfigContentDao;
    @Resource
    private SysParamConfigEnDao sysParamConfigEnDao;
    @Resource
    private SysLisenceManageDao sysLisenceManageDao;
    @Autowired
    private SysVersionDao sysVersionDao;
    @Autowired
    private SysAppModuleEnDao sysAppModuleEnDao;

    @Autowired
    public void setBaseDao(SysAppModuleDao sysAppModuleDao) {
        this.baseDao = sysAppModuleDao;
    }

    private static String SENDKEY_SUCCEED_MSG = "密钥生成成功";
    private static String SENDKEY_ERROR_MSG = "密钥生成失败";
    private static String ENCORD_SUCCEED_MSG = "菜单加密成功";
    private static String RECEIVE_APPLY_SUCCESS_MSG = "应用下发成功";
    private static String RECEIVE_APPLY_FAIL_MSG = "应用下发失败";
    private static String SEND_APPMOUDLE_URL="/api/SysAppModule/receiveDate";


    /**
     * 应用管理分页查询接口
     *
     * @param baseAppModuluVo 对象
     * @param pageSize 第几页
     * @param pageNum 每页数量
     * @return ReturnResult 对象
     * @author dingxu
     * @date 2019-04-02 14:25
     */
    @Override
    public ReturnResult page(SysAppModuleVo baseAppModuluVo, int pageSize, int pageNum) {
        PageHelper.startPage(pageNum,pageSize);
        PageHelper.orderBy(" status,create_time desc");
        Example example = new Example(SysAppModule.class);
        Example.Criteria criteria = example.createCriteria();
        if(StringUtil.isNotEmpty(baseAppModuluVo.getName())){
            criteria.andLike("name","%"+baseAppModuluVo.getName()+"%");
        }
        if(StringUtil.isNotEmpty(baseAppModuluVo.getCode())){
            criteria.andLike("code","%"+baseAppModuluVo.getCode()+"%");
        }
        if(StringUtil.isNotEmpty(baseAppModuluVo.getStatus())){
            criteria.andEqualTo("status", baseAppModuluVo.getStatus());
        }
        criteria.andEqualTo("removeTag", BaseConstant.REMOVE_TAG_NO);

        List<SysAppModule> list= sysAppModuleDao.selectByExample(example);
        PageInfo<SysAppModule> page=new PageInfo<SysAppModule>(list);
        Map<String,Object> map=new HashedMap();
        map.put("page",page.getList());
        return new ReturnResult(page.getList(),page.getTotal(),page.isHasNextPage());
    }



    /**
     * 添加修改应用信息
     *
     *@author dingxu
     *@date 2019-04-02 14:25
     *@param sysAppModuleVo 对象
     *@return ReturnResult
     */
    @Override
    public ReturnResult addOrUpdate(SysAppModuleVo sysAppModuleVo) {
        if (sysAppModuleVo.getId() == null || "".equals(sysAppModuleVo.getId())) {
            SysAppModule sysAppModule = new SysAppModule();
            sysAppModule.setId(BaseUtil.uId());
            sysAppModule.setName(sysAppModuleVo.getName());
            sysAppModule.setCode(sysAppModuleVo.getCode());
            sysAppModule.setStatus(sysAppModuleVo.getStatus());
            sysAppModule.setDescription(sysAppModuleVo.getDescription());
            sysAppModule.setCreateTime(new Date());
            sysAppModule.setRemoveTag(BaseConstant.REMOVE_TAG_NO);
            int id = sysAppModuleDao.insert(sysAppModule);
            if (id <= 0) {
                return new ReturnResult(BaseConstant.DATABASE_ERROR_INSERT);
            }else{
                //设置应用下的菜单
                setBaseAppModuleMenus(sysAppModuleVo.getMenuIds(), sysAppModule.getId());
                //处理应用状态
                if(sysAppModule.getStatus().equals('1')){
                    setNotAppIdStateNo(sysAppModule.getId());
                }
            }
        } else {
            SysAppModule sysAppModule = sysAppModuleDao.selectByPrimaryKey(sysAppModuleVo.getId());
            sysAppModule.setName(sysAppModuleVo.getName());
            sysAppModule.setCode(sysAppModuleVo.getCode());
            sysAppModule.setStatus(sysAppModuleVo.getStatus());
            sysAppModule.setDescription(sysAppModuleVo.getDescription());
            sysAppModule.setRemoveTag(BaseConstant.REMOVE_TAG_NO);
            int id = sysAppModuleDao.updateByPrimaryKey(sysAppModule);
            if (id <= 0) {
                return new ReturnResult(BaseConstant.DATABASE_ERROR_UPDATE);
            }else{
                //设置应用下的菜单
                setBaseAppModuleMenus(sysAppModuleVo.getMenuIds(), sysAppModule.getId());
                //处理应用状态
                if(sysAppModule.getStatus().equals("1")){
                    setNotAppIdStateNo(sysAppModule.getId());
                }
            }
        }
        return new ReturnResult(BaseConstant.DATABASE_SUCCEED_MSG);
    }


    /**
     * 删除应用类型
     *
     *@author dingxu
     *@date 2019-04-02 14:25
     *@param ids id数组集字符串
     *@return ReturnResult
     */

    public ReturnResult delete(String ids) {
        List<SysAppModule> list =findStatusYes();
        if(list.size()<=1){
            return new ReturnResult(ErrorCode.CODE_1, ErrorCode.CODE_500_MSG);
        }
        String[] idList=ids.split(",");
        boolean flage=true;
        StringBuffer stringBuffer=new StringBuffer();
        for (String id:idList){
            SysAppModule sysAppModule = sysAppModuleDao.selectByPrimaryKey(id);
            sysAppModule.setRemoveTag(BaseConstant.REMOVE_TAG_YES);
            int num= sysAppModuleDao.updateByPrimaryKey(sysAppModule);
            if(num>0){
                flage=true;
            }else{
                stringBuffer.append("");
            }
        }
        if(flage){
            return new ReturnResult();
        }else{
            return new ReturnResult(ErrorCode.CODE_1,ErrorCode.CODE_101_MSG);
        }
    }

    /**
     * 生成密钥
     *
     *@author dingxu
     *@date 2019-04-09 14:25
     *@param id 主键
     *@return ReturnResult
     */

    @Override
    public ReturnResult sendKey(String id) throws Exception {
        SysAppModule sysAppModule = sysAppModuleDao.selectByPrimaryKey(id);
        if(sysAppModule ==null){
            return new ReturnResult(ErrorCode.CODE_100,ErrorCode.CODE_200_MSG);
        }
        KeyPair keyPair = RSAHelper.getPublicKeyAndPrivateKey();
        //公钥
        PublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        //私钥
        PrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
        //私钥串
        String privateKeyString= RSAHelper.getKeyPrivateString(privateKey, sysAppModule.getCode());
        //公钥字符串
        String publicKeyString= RSAHelper.getKeyPubliceString(publicKey);
        sysAppModule.setPrivateKey(privateKeyString);
        sysAppModule.setPublicKey(publicKeyString);
        int num= sysAppModuleDao.updateByPrimaryKey(sysAppModule);
        if(num<=0){
            return new ReturnResult(SENDKEY_ERROR_MSG);
        }else{
            return new ReturnResult(SENDKEY_SUCCEED_MSG);
        }
    }

    /**
     * 设置应用菜单集合
     *
     *@author dingxu
     *@date 2019-04-03 14:25
     *@param menuIds id数组集字符串
     *@param appId 应用主键id
     */
    private void setBaseAppModuleMenus(String menuIds,String appId){
        sysAppMenuDao.deleteByAppId(appId);
        if(StringUtil.isNotEmpty(menuIds)){
            String[] menuIdList=menuIds.split(",");
            for (String menuId:menuIdList){
                SysAppMenu sysAppMenu =new SysAppMenu();
                sysAppMenu.setId(BaseUtil.uId());
                sysAppMenu.setCreateTime(new Date());
                sysAppMenu.setMenuId(menuId);
                sysAppMenu.setAppId(appId);
                sysAppMenuDao.insert(sysAppMenu);
            }
        }
    }

    /**
     * 批量将所有非当前id应用置为无效
     *
     *@author dingxu
     *@date 2019-04-03 14:25
     *@param appId 应用主键id
     */
    private void setNotAppIdStateNo(String appId){
        sysAppModuleDao.setNotAppIdStateNo(appId);
    }


    /**
     * 根据当前应用id加密菜单表
     *
     *@author dingxu
     *@date 2019-04-09 14:25
     *@param id 主键
     *@return ReturnResult
     */
    public ReturnResult encordBassMenu(String id) throws Exception {
        //获取当前id应用
        SysAppModule sysAppModule = sysAppModuleDao.selectByPrimaryKey(id);
        if(sysAppModule ==null){
            return new ReturnResult(ErrorCode.CODE_100,ErrorCode.CODE_200_MSG);
        }
        //获取公钥
        String publicKeyString= sysAppModule.getPublicKey();

        List<SysMenu> sysMenuList = sysMenuDao.selectAll();
        List<SysMenuEn> sysMenuEnList =new ArrayList<>();
        //清空加密表
        sysMenuEnDao.truncateBaseMenuEn();
        //加密处理
        for(SysMenu sysMenu : sysMenuList){
            Map<String,Object> stringObjectMap= JavaBeanUtil.convertBeanToMap(sysMenu);
            SysMenuEn sysMenuEn =new SysMenuEn();
            sysMenuEn.setId(RSAHelper.encodeString(publicKeyString, sysMenu.getId()));
            sysMenuEn.setMenuGrade(RSAHelper.encodeString(publicKeyString,String.valueOf(sysMenu.getMenuGrade())));
            sysMenuEn.setMenuIcon(RSAHelper.encodeString(publicKeyString, sysMenu.getMenuIcon()));
            sysMenuEn.setMenuName(RSAHelper.encodeString(publicKeyString, sysMenu.getMenuName()));
            sysMenuEn.setMenuType(RSAHelper.encodeString(publicKeyString, sysMenu.getMenuType()));
            sysMenuEn.setMenuUrl(RSAHelper.encodeString(publicKeyString, sysMenu.getMenuUrl()));
            sysMenuEn.setParentId(RSAHelper.encodeString(publicKeyString, sysMenu.getParentId()));
            sysMenuEn.setPermission(RSAHelper.encodeString(publicKeyString, sysMenu.getPermission()));
            sysMenuEn.setSort(RSAHelper.encodeString(publicKeyString,String.valueOf(sysMenu.getSort())));
            sysMenuEnList.add(sysMenuEn);
            sysMenuEnDao.insert(sysMenuEn);
        }

        /*//加密系统配置表
        encordParamConfig(id);*/


        return new ReturnResult(ENCORD_SUCCEED_MSG);
    }


    /**
     * 根据当前应用id加密系统配置表
     *
     *@author dingxu
     *@date 2019-04-09 14:25
     *@param id 主键
     *@return ReturnResult
     */
    @Override
    public ReturnResult encordParamConfig(String id) throws Exception {
        //获取当前id应用
        SysAppModule sysAppModule = sysAppModuleDao.selectByPrimaryKey(id);
        if(sysAppModule ==null){
            return new ReturnResult(ErrorCode.CODE_100,ErrorCode.CODE_200_MSG);
        }
        //获取公钥
        //清空配置加密表
        sysParamConfigEnDao.truncateParamConfigEn();
        String publicKeyString= sysAppModule.getPublicKey();
        List<ParamConfig> paramConfigList= sysParamConfigContentDao.selectAll();
        for(ParamConfig paramConfig:paramConfigList){
            ParamConfigEn paramConfigEn= new ParamConfigEn();
            paramConfigEn.setId(RSAHelper.encodeString(publicKeyString,paramConfig.getId()));
            paramConfigEn.setInfo(RSAHelper.encodeString(publicKeyString,paramConfig.getInfo()));
            paramConfigEn.setParamid(RSAHelper.encodeString(publicKeyString,paramConfig.getParamid()));
            paramConfigEn.setRemark(RSAHelper.encodeString(publicKeyString,paramConfig.getRemark()));
            paramConfigEn.setRemovetag(RSAHelper.encodeString(publicKeyString,paramConfig.getRemovetag()));
            sysParamConfigEnDao.insert(paramConfigEn);
        }
        return new ReturnResult(ENCORD_SUCCEED_MSG);
    }

    /**
     * 根据当前应用id解密菜单表
     *
     *@author dingxu
     *@date 2019-04-09 14:25
     *@param id 主键
     *@return ReturnResult
     */
    public ReturnResult decordParamConfig(String id) throws Exception {
        //
        //获取当前id应用
        SysAppModule sysAppModule = sysAppModuleDao.selectByPrimaryKey(id);
        //获取私钥
        String privateKeyString= sysAppModule.getPrivateKey();
        String password= sysAppModule.getCode();
        //清空菜单表
        sysParamConfigContentDao.truncateParamConfig();
        List<ParamConfigEn>  paramConfigEnLists= sysParamConfigEnDao.selectAll();
        for(ParamConfigEn paramConfigEn:paramConfigEnLists){
            ParamConfig paramConfig=new ParamConfig();
            paramConfig.setId(RSAHelper.decodeString(privateKeyString,paramConfigEn.getId(),password));
            paramConfig.setInfo(RSAHelper.decodeString(privateKeyString,paramConfigEn.getInfo(),password));
            paramConfig.setParamid(RSAHelper.decodeString(privateKeyString,paramConfigEn.getParamid(),password));
            paramConfig.setRemark(RSAHelper.decodeString(privateKeyString,paramConfigEn.getRemark(),password));
            paramConfig.setRemovetag(RSAHelper.decodeString(privateKeyString,paramConfigEn.getRemovetag(),password));
            paramConfig.setCreatetime(new Date());
            sysParamConfigContentDao.insert(paramConfig);
        }
        return new ReturnResult(ENCORD_SUCCEED_MSG);
    }

    /**
     * 根据当前应用id解密系统配置表
     *
     *@author dingxu
     *@date 2019-04-09 14:25
     *@param id 主键
     *@return ReturnResult
     */
    public ReturnResult decordBassMenu(String id) throws Exception {
        //
        //获取当前id应用
        SysAppModule sysAppModule = sysAppModuleDao.selectByPrimaryKey(id);
        //获取私钥
        String privateKeyString= sysAppModule.getPrivateKey();
        String password= sysAppModule.getCode();
        //清空菜单表
        sysMenuDao.truncateBaseMenu();
        List<SysMenuEn> sysMenuEnLists = sysMenuEnDao.selectAll();
        List<SysMenu> sysMenuLists =new ArrayList<>();
        for(SysMenuEn sysMenuEn : sysMenuEnLists){
            SysMenu sysMenu =new SysMenu();
            sysMenu.setId(RSAHelper.decodeString(privateKeyString, sysMenuEn.getId(),password));
            sysMenu.setMenuGrade(Integer.parseInt(RSAHelper.decodeString(privateKeyString, sysMenuEn.getMenuGrade(),password)));
            sysMenu.setMenuIcon(RSAHelper.decodeString(privateKeyString, sysMenuEn.getMenuIcon(),password));
            sysMenu.setMenuName(RSAHelper.decodeString(privateKeyString, sysMenuEn.getMenuName(),password));
            sysMenu.setMenuType(RSAHelper.decodeString(privateKeyString, sysMenuEn.getMenuType(),password));
            sysMenu.setMenuUrl(RSAHelper.decodeString(privateKeyString, sysMenuEn.getMenuUrl(),password));
            sysMenu.setParentId(RSAHelper.decodeString(privateKeyString, sysMenuEn.getParentId(),password));
            sysMenu.setPermission(RSAHelper.decodeString(privateKeyString, sysMenuEn.getPermission(),password));
            sysMenu.setSort(Integer.parseInt(RSAHelper.decodeString(privateKeyString, sysMenuEn.getSort(),password)));
            sysMenu.setCreateTime(new Date());
            sysMenuLists.add(sysMenu);
            sysMenuDao.insert(sysMenu);
        }

       /* //解密系统配置表
        decordParamConfig(id);*/
        return new ReturnResult(ENCORD_SUCCEED_MSG);
    }

    /**
     * 获取需要关联的应用集合信息
     *
     * @author sunli
     * @param status
     * @return ReturnResult
     */
    @Override
    public ReturnResult getAllApply(String status) {
        List<SysAppModule> lists=new ArrayList<SysAppModule>();
        System.out.print(status);
        List<SysAppModule> list= sysAppModuleDao.selectAll();
        lists.addAll(list);
        if (lists != null) {
            return new ReturnResult(lists);
        }else{
            return new ReturnResult(ErrorCode.CODE_700, ErrorCode.CODE_700_MSG);
        }
    }

    /**
     * 对应用数据进行下发
     *
     * @author sunli
     * @date 2019-04-18
     * @param id 应用id
     * @return ReturnResult
     */
    @Override
    public ReturnResult sendApply(String url,String id) {
        SysLisenceManage baseLisenceManage = sysLisenceManageDao.selectByPrimaryKey(id);
        SysVersion sysVersion = sysVersionDao.selectByPrimaryKey(baseLisenceManage.getVersonId());
        SysAppModule sysAppModule = sysAppModuleDao.selectByPrimaryKey(sysVersion.getApplyId());
        SysAppModuleEn sysAppModuleEn =new SysAppModuleEn();
        String lisence=baseLisenceManage.getLisence();
        sysAppModuleEn.setCode(DESHelper.encrypt(sysAppModule.getCode(),lisence));
        sysAppModuleEn.setDescription(DESHelper.encrypt(sysAppModule.getDescription(),lisence));
        sysAppModuleEn.setId(DESHelper.encrypt(sysAppModule.getId(),lisence));
        sysAppModuleEn.setMenuIds(DESHelper.encrypt(sysAppModule.getMenuIds(),lisence));
        sysAppModuleEn.setName(DESHelper.encrypt(sysAppModule.getName(),lisence));
        sysAppModuleEn.setPrivateKey(DESHelper.encrypt(sysAppModule.getPrivateKey(),lisence));
        sysAppModuleEn.setPublicKey(DESHelper.encrypt(sysAppModule.getPublicKey(),lisence));
        sysAppModuleEn.setRemoveTag(DESHelper.encrypt(sysAppModule.getRemoveTag(),lisence));
        sysAppModuleEn.setStatus(DESHelper.encrypt(sysAppModule.getStatus(),lisence));

        List<SysAppModuleEn> baseAppModuleList=new ArrayList<SysAppModuleEn>();
        baseAppModuleList.add(sysAppModuleEn);
        RestTemplate restTemplate = new RestTemplate();
        url = url+SEND_APPMOUDLE_URL;
        //String url="http://127.0.0.1:8080/api/baseVersion/receiveDate";//需要外置
        JSONArray jsonObject = JSONArray.fromObject(baseAppModuleList);
        String message= PostClient.postRequest(restTemplate,jsonObject.toString(),url);
        if(message.equals("success")){
            return new ReturnResult(RECEIVE_APPLY_SUCCESS_MSG);
        }else{
            return new ReturnResult(RECEIVE_APPLY_FAIL_MSG);
        }
    }


    /**
     * 处理下发的应用数据
     *
     * @author sunli
     * @date 2019-04-18
     * @param sysAppModule 应用对象
     * @return ReturnResult
     */
    @Override
    public ReturnResult receiveApplyData(SysAppModule sysAppModule) {

        int num = sysAppModuleDao.insert(sysAppModule);
        if(num<=0){
            return new ReturnResult(BaseConstant.CODE_SUCCESS);
        }
        return new ReturnResult(BaseConstant.CODE_ERROR);
    }

    /**
     * 对下发的数据进行保存
     *
     * @author dingxu
     * @date 2019-04-18
     * @param sysAppModuleEn
     * @return
     */
    @Override
    public ReturnResult receiveAppModule(SysAppModuleEn sysAppModuleEn) {
        sysAppModuleEnDao.truncateAppModuleEn();
        int num= sysAppModuleEnDao.insert(sysAppModuleEn);
        if(num<=0){
            return new ReturnResult(BaseConstant.CODE_SUCCESS);
        }
        return new ReturnResult(BaseConstant.CODE_ERROR);
    }


    /**
     * 查询当前是否有有效应用
     *
     *@author dingxu
     *@date 2019-04-03 14:25
     */
    public List<SysAppModule> findStatusYes(){
        return  sysAppModuleDao.findStatusYes();
    }
}